﻿Imports System.Reflection.Emit
Imports VBParser

Namespace Compiler.Semantic
    Public Class ClassDescription
        Inherits GenericTypeDescription

        Private m_classTypeBuilder As TypeBuilder
        Public Overrides Property UnderlyingType() As System.Type
            Get
                Return m_classTypeBuilder
            End Get
            Set(ByVal value As System.Type)
                If Not TypeOf value Is TypeBuilder Then
                    Throw New ArgumentOutOfRangeException("value", "The underlying type of a ClassDescription must be TypeBuilder")
                End If
                m_classTypeBuilder = TryCast(value, TypeBuilder)
            End Set
        End Property

        Public Sub New(ByVal parent As NameContainer, ByVal syntaxNode As ClassDeclaration)
            MyBase.New(parent)
            Debug.Assert(syntaxNode IsNot Nothing)
            m_interfaces = New List(Of TypeReference)

            m_classSyntaxNode = syntaxNode
        End Sub

        'class specified contents

        Private m_baseClass As TypeReference
        Public Property BaseClass() As TypeReference
            Get
                Return m_baseClass
            End Get
            Set(ByVal value As TypeReference)
                m_baseClass = value
            End Set
        End Property

        Private m_interfaces As List(Of TypeReference)
        Public ReadOnly Property Interfaces() As IList(Of TypeReference)
            Get
                Return m_interfaces
            End Get
        End Property

        Private m_classSyntaxNode As ClassDeclaration
        Public Overrides Property SyntaxNode() As VBParser.Tree
            Get
                Return m_classSyntaxNode
            End Get
            Set(ByVal value As VBParser.Tree)
                m_classSyntaxNode = TryCast(value, ClassDeclaration)
            End Set
        End Property

        Public Overrides Function SearchChild(ByVal childBinder As Binder) As NameContainer
            'search these places:
            '1. GenericTypeDescription.GenericParameters
            '2. Nested Types

            'the base classes has already implmented them all
            Return MyBase.SearchChild(childBinder)
        End Function
        '==========================Semantic Analysis==========================

        Public Overrides Function DeclareSyntaxNode() As Boolean
            Dim finalResult As Boolean = True

            'parse name, generic paramters and nested types

            '1. parse name
            Dim nameSymbol = Symbol.Get(m_classSyntaxNode.Name.Name)
            Dim typeParamCount As Integer = m_classSyntaxNode.TypeParameters.Count

            Me.Name = nameSymbol

            '2. parse typeparameters
            For Each typeParam In m_classSyntaxNode.TypeParameters
                finalResult = DeclareTypeParameter(typeParam) AndAlso finalResult
            Next

            '3. parse nested types
            finalResult = DeclareNestedTypes() AndAlso finalResult

            Return finalResult
        End Function
    End Class
End Namespace